package com.lry.easyExcel.utils;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;

public class ByteUtils {

    static final char[] digits = {
            '0', '1', '2', '3', '4', '5',
            '6', '7', '8', '9', 'a', 'b',
            'c', 'd', 'e', 'f', 'g', 'h',
            'i', 'j', 'k', 'l', 'm', 'n',
            'o', 'p', 'q', 'r', 's', 't',
            'u', 'v', 'w', 'x', 'y', 'z'
    };

    public static boolean checkHex(String hexStr) {
        if (StringUtils.isEmpty(hexStr))
            return false;
        hexStr = hexStr.toLowerCase();
        char[] cs = hexStr.toCharArray();
        for (char c : cs) {
            if (!isHexChar(c)) {
                return false;
            }
        }
        return true;
    }

    private static boolean isHexChar(char c) {
        return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f');
    }

    public static boolean checkBytebuf(ByteBuf buf) {
        if (null == buf) {
            return false;
        }
        if (buf.readableBytes() <= 0)
            return false;

        return true;
    }

    public static String toHexStr(float f) {
        ByteBuf buf = Unpooled.buffer(4);
        buf.writeFloat(f);
        return preBufWithoutSpace(buf);
    }
    //返回16进制，长度为16
    public static String toHexStr(long l) {
        ByteBuf buf = Unpooled.buffer(8);
        buf.writeLong(l);
        return preBufWithoutSpace(buf);
    }
    //返回16进制，长度为len
    public static String toHexStr(long l,int len) {
        ByteBuf buf = Unpooled.buffer(8);
        buf.writeLong(l);
        String hexStr = preBufWithoutSpace(buf);
        return hexStr.substring(8,hexStr.length());
    }

    public static String preBufWithoutSpace(ByteBuf buf) {
        if (null == buf)
            return null;
        byte[] bytes = new byte[buf.readableBytes()];
        buf.getBytes(buf.readerIndex(), bytes);
        return toHexStr(bytes);
    }

    public static String preBuf(ByteBuf buf) {
        if (null == buf)
            return null;
        byte[] bytes = new byte[buf.readableBytes()];
        buf.getBytes(buf.readerIndex(), bytes);
        return toHexStrWithSpace(bytes);
    }


    /**
     * hex字符串转byte数组
     *
     * @param inHex 待转换的Hex字符串
     * @return 转换后的byte数组结果
     */
    public static byte[] hexToBytes(String inHex) {
        if (StringUtils.isEmpty(inHex)) {
            return new byte[0];
        }
        //长度是否是偶数
        boolean isEven = (inHex.length() & 1) == 0;
        //如果是奇数
        if (!isEven) {
            inHex = "0" + inHex;
        }
        byte[] result = new byte[inHex.length() / 2];
        int j = 0;
        for (int i = 0; i < inHex.length(); i += 2) {
            result[j++] = hexToByte(inHex.substring(i, i + 2));
        }
        return result;
    }

    public static byte hexToByte(String hexStr) {
        if (StringUtils.isEmpty(hexStr) || hexStr.length() > 2)
            return 0;
        return (byte) Integer.parseInt(hexStr, 16);
    }

    public static String toHexStr(byte b) {
        return toUnsignedString0(b, 4, 2);
    }

    public static String toHexStr(short b) {
        return toUnsignedString0(b, 4, 4);
    }

    public static String toHexStr(int b) {
        return toUnsignedString0(b, 4, 8);
    }

    public static String toHexStr(int b, int len) {
        return toUnsignedString0(b, 4, len);
    }

    public static String toHexStr(byte[] bytes) {
        if (null == bytes || bytes.length == 0)
            return "";
        StringBuffer sb = new StringBuffer();
        for (byte b : bytes) {
            sb.append(toHexStr(b));
        }
        return sb.toString();
    }

    public static String toHexStrWithSpace(byte[] bytes) {
        if (null == bytes || bytes.length == 0)
            return "";
        StringBuffer sb = new StringBuffer();
        for (byte b : bytes) {
            sb.append(toHexStr(b)).append(" ");
        }
        return sb.toString();
    }

    //shift=1 二进制 ，=3 8进制 ， =4 16进制
    private static String toUnsignedString0(int val, int shift, int len) {
        char[] buf = new char[len];
        for (int i = 0; i < buf.length; ++i) {
            buf[i] = '0';
        }
        formatUnsignedInt(val, shift, buf, 0, len);
        return new String(buf).toUpperCase();
    }

    private static int formatUnsignedInt(int val, int shift, char[] buf, int offset, int len) {
        int charPos = len;
        int radix = 1 << shift;
        int mask = radix - 1;
        do {
            buf[offset + --charPos] = digits[val & mask];
            val >>>= shift;
        } while (val != 0 && charPos > 0);

        return charPos;
    }

}
